﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DAL.DALObjects;
using System.Data;

namespace ShareIt_MVC3.Models
{
    /// <summary>
    /// Klasse für die Methoden die die Leihvorgänge betreffen.
    /// </summary>
    public class LendingCollection
    {
        string _databaseFile;   // String zur Access-Datei, wird im Konstruktor initialisiert        
        UserCollection userColl = new UserCollection();
        ResourceCollection resColl = new ResourceCollection();

        /// <summary>
        /// Lending-Collection Konstruktor 
        /// </summary>
        public LendingCollection() 
        {   
            // hier wird der Pfad zur Access-Datei aus web.config gelesen
            _databaseFile = System.Configuration.ConfigurationManager.AppSettings["AccessFileName"];
        }
        
        /// <summary>
        /// Hilfsmethode zur Erstellung eines Lending Objektes
        /// </summary>
        /// <param name="_dr"></param>
        /// <returns></returns>
        private Lending CreateLendingObject(DataRow _dr)
        {
            Lending lending = new Lending
            {
                ID = (int)_dr["LID"],
                Resource = resColl.GetResourceByID((int)_dr["LResourceId"]),
                Lender = userColl.GetUserById((int)_dr["LLenderId"]),
                DateOfLending = _dr["LDateOfLending"].ToString(),
                DateOfReturning = _dr["LDateOfReturning"].ToString()
            };

            return lending;
        }

        public List<Lending> GetAllLendings()
        {
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);
            
            DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetAllLendings");

            //das DataSet enthält nur eine DataTable
            DataTable _myDataTable = _myDataSet.Tables[0];

            //Instantiieren eine Liste von User-Objekten
            List<Lending> lendings = new List<Lending>();

            //Lesen wir jetzt Zeile (DataRow) für Zeile
            foreach (DataRow _dr in _myDataTable.Rows)
            {
                Lending lending = CreateLendingObject(_dr);
                lendings.Add(lending);
            }

            return lendings;

        }

        /// <summary>
        /// Hier wird der Leihvorgang der übergebenen ID zurückgegeben.
        /// </summary>
        /// <param name="lendingId"></param>
        /// <returns></returns>
        public Lending GetLendingById(int lendingId)
        {
            //Hier wird ein DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            //Jetzt müssen wir erstmal den Übergabeparameter hinzufügen
            _myProvider.AddParam("LID", lendingId, DAL.DataDefinition.enumerators.SQLDataType.INT);

            Lending lending = null;

            try
            {
                //Hier wird unser Dataset initialisiert
                DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetLendingById");

                //füllen wir eine DataTable mit dem DataSet
                DataRow _dr = _myDataSet.Tables[0].Rows[0];
                lending = CreateLendingObject(_dr);
            }
            catch { }


            return lending;
        }

        /// <summary>
        /// Hier werden alles Leihvorgänge ausgegeben, die der User mit der übergebenen ID getätigt und die Ressource noch nicht zurückgegeben hat.
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public List<Lending> GetLentResourcesByUserID(int userid)
        {
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);
            _myProvider.AddParam("UID", userid, DAL.DataDefinition.enumerators.SQLDataType.INT);
            UserCollection userColl = new UserCollection();
            User owner = userColl.GetUserById(userid);
            DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetLentResourcesByUserId");

            //das DataSet enthält nur eine DataTable
            DataTable _myDataTable = _myDataSet.Tables[0];

            //Instantiieren eine Liste von User-Objekten
            List<Lending> lendings = new List<Lending>();

            //Lesen wir jetzt Zeile (DataRow) für Zeile
            foreach (DataRow _dr in _myDataTable.Rows)
            {
                Lending lending = CreateLendingObject(_dr);
                lendings.Add(lending);
            }

            return lendings;

        }

        /// <summary>
        /// Hier werden alles Leihvorgänge ausgegeben, die der User mit der übergebenen ID getätigt und die Ressource schon zurückgegeben hat.
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public List<Lending> GetLentResourcesHistoryByUserID(int userid)
        {
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);
            _myProvider.AddParam("UID", userid, DAL.DataDefinition.enumerators.SQLDataType.INT);
            UserCollection userColl = new UserCollection();
            User owner = userColl.GetUserById(userid);
            DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetLentResourcesHistoryByUserId");

            //das DataSet enthält nur eine DataTable
            DataTable _myDataTable = _myDataSet.Tables[0];

            //Instantiieren eine Liste von User-Objekten
            List<Lending> lendings = new List<Lending>();

            //Lesen wir jetzt Zeile (DataRow) für Zeile
            foreach (DataRow _dr in _myDataTable.Rows)
            {
                Lending lending = CreateLendingObject(_dr);
                lendings.Add(lending);
            }

            return lendings;

        }

        /// <summary>
        /// Gibt alle Ressourcen eines bestimmten Benutzers zurück.
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public List<Lending> GetBorrowedResourcesByUserID(int userid)
        {
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);
            _myProvider.AddParam("UID", userid, DAL.DataDefinition.enumerators.SQLDataType.INT);
            
            User owner = userColl.GetUserById(userid);
            DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetBorrowedResourcesByUserId");

            //das DataSet enthält nur eine DataTable
            DataTable _myDataTable = _myDataSet.Tables[0];

            //Instantiieren eine Liste von User-Objekten
            List<Lending> lendings = new List<Lending>();

            //Lesen wir jetzt Zeile (DataRow) für Zeile
            foreach (DataRow _dr in _myDataTable.Rows)
            {
                Lending lending = CreateLendingObject(_dr);
                lendings.Add(lending);
            }
            return lendings;

        }

        /// <summary>
        /// Gibt alle Ressourcen eines bestimmten Benutzers zurück.
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public List<Lending> GetBorrowedResourcesHistoryByUserID(int userid)
        {
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);
            _myProvider.AddParam("UID", userid, DAL.DataDefinition.enumerators.SQLDataType.INT);

            User owner = userColl.GetUserById(userid);
            DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetBorrowedResourcesHistoryByUserId");

            //das DataSet enthält nur eine DataTable
            DataTable _myDataTable = _myDataSet.Tables[0];

            //Instantiieren eine Liste von User-Objekten
            List<Lending> lendings = new List<Lending>();

            //Lesen wir jetzt Zeile (DataRow) für Zeile
            foreach (DataRow _dr in _myDataTable.Rows)
            {
                Lending lending = CreateLendingObject(_dr);
                lendings.Add(lending);
            }
            return lendings;

        }

        /// <summary>
        /// Gibt alle Leihvorgänge aus, die eine bestimmte Ressource betreffen.
        /// </summary>
        /// <param name="resourceId"></param>
        /// <returns></returns>
        public Lending GetLendingForResource(int resourceId)
        {
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);
            _myProvider.AddParam("ResourceId", resourceId, DAL.DataDefinition.enumerators.SQLDataType.INT);

            Lending lending = null;

            try
            {
                //Hier wird unser Dataset initialisiert
                DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetLendingForResource");

                //füllen wir eine DataTable mit dem DataSet
                DataRow _dr = _myDataSet.Tables[0].Rows[0];
                lending = CreateLendingObject(_dr);
            }
            catch { }


            return lending;

        }

        /// <summary>
        /// Updated ein Lending
        /// </summary>
        /// <param name="lending"></param>
        /// <returns></returns>
        public int UpdateLending(Lending lending)
        {

            //DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            // Jetzt müssen wir erstmal die Übergabeparameter hinzufügen 
            // (Parameter in derselben Reihenfolge wie in der Access-Query)
            _myProvider.AddParam("DateOfReturning", lending.DateOfReturning, DAL.DataDefinition.enumerators.SQLDataType.DATETIME);
            _myProvider.AddParam("LID", lending.ID, DAL.DataDefinition.enumerators.SQLDataType.INT);

            //Ausführen und veränderte Zeilen zurückgeben
            int _changedSets = _myProvider.MakeStoredProcedureAction("QUpdateLendingReturnDate");

            return _changedSets;
        }

        /// <summary>
        /// Setzt einen neuen Leihvorgang auf.
        /// </summary>
        /// <param name="lending"></param>
        /// <returns></returns>
        public int InsertLending(Lending lending)
        {

            //DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            // Jetzt müssen wir erstmal die Übergabeparameter hinzufügen 
            // (Parameter in derselben Reihenfolge wie in der Acess-Query)
            _myProvider.AddParam("ResourceId", lending.Resource.ID, DAL.DataDefinition.enumerators.SQLDataType.INT);
            _myProvider.AddParam("LenderId", lending.Lender.ID, DAL.DataDefinition.enumerators.SQLDataType.INT);
            _myProvider.AddParam("DateOfLending", lending.DateOfLending, DAL.DataDefinition.enumerators.SQLDataType.DATETIME);
            
            // kleiner Workaround
            if(lending.DateOfReturning != null)
                _myProvider.AddParam("DateOfReturning", lending.DateOfReturning, DAL.DataDefinition.enumerators.SQLDataType.DATETIME);

            //Ausführen und veränderte Zeilen zurückgeben
            int _changedSets = _myProvider.MakeStoredProcedureAction("QLendingInsert");

            return _changedSets;
        } //updateUser()


        /// <summary>
        /// Löschen eines Lending Objekts
        /// </summary>
        /// <param name="_User">User-Objekt mit geänderten Attributen</param>
        /// <returns>1 falls delete erfolgreich </returns>
        public int DeleteLending(Lending lending)
        {

            //DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            // Übergabeparameter ID hinzufügen 
            _myProvider.AddParam("ID", lending.ID, DAL.DataDefinition.enumerators.SQLDataType.INT);

            //Ausführen und veränderte Zeilen zurückgeben
            int _changedSets = _myProvider.MakeStoredProcedureAction("QLendingDeleteById");

            return _changedSets;
        } //deleteUser()
    }
}